package dramsy_christian_bellamn_floyd;

/**
 * Outils utilitaire pour la numerotation topologique
 * @author <a href="mailto:christian.dramsy@gmail.com">DRAMSY Christian</a>
 */
public class UtilitaireNumerotationTopologique {

    /**
     * CalCue la numeroation topographique et retourne dans quel tour de boucle(s0,s1,s2,...) appartient un sommet
     * @param graphe.getMatriceAdj().length
     * @return Un tableau contenant le numero de tour de boucle auquel appartient le sommet
     */
    public static int[] calulNumerotationTopographique(Graphe graphe) {

        if (graphe.containsCircuit()) {
            return null;
        }

        //  Numero des sommets
        int[] numeroSommet = new int[graphe.getMatriceAdj().length];

        int k = 0;
        boolean fin = false;
        //  Nombre de predecesseur d'un sommet
        int[] nombrePred = new int[graphe.getMatriceAdj().length];

        for (int i = 0; i < graphe.getMatriceAdj().length; i++) {
            //  affectation du nombre de predecesseur pour chaque sommet
            nombrePred[i] = UtilitaireAffichage.nbTrueValue(graphe.predecesseurs(i));
        }//for

        while (!fin) {
            //  true si il y a au moin un sommet contient un predecesseur
            boolean sommetAvecPred = false;
            int[] clonePred = nombrePred.clone();
            for (int i = 0; i < clonePred.length; i++) {
                if (clonePred[i] == 0) {
                    nombrePred[i] = -1;
                    numeroSommet[i] = k;
                    sommetAvecPred = true;
                    //  les successeur de i
                    boolean[] successeur = graphe.successeurs(i);
                    //  parcours des successeurs
                    for (int j = 0; j < successeur.length; j++) {
                        if (successeur[j] == true) {
                            //  decrementation du nombre de predecesseur
                            nombrePred[j]--;
                        }
                    }
                }
            }

            fin = !sommetAvecPred;
            if (!fin) {
                k++;
            }
        }//while

        return numeroSommet;
    }

    /**
     * Retourne le nombre de couche topologique, par rapport à la numerotation stocké dans un tableau
     * @param numerotation Le resultat du calcul de la numerotation topologique
     * @return 
     */
    public static int nbCoucheTopologique(int[] numerotation) {
        int max = -1;
        for (int i = 0; i < numerotation.length; i++) {
            if (max < numerotation[i]) {
                max = numerotation[i];
            }
        }
        return max;
    }

    /**
     * Affiche le resultat du calcul de numerotation topologique
     * @param result
     */
    public static void AfficheNumerotation(int[] result) {
        int max = -1;
        for (int i = 0; i < result.length; i++) {
            if (max < result[i]) {
                max = result[i];
            }
        }

        for (int i = 0; i <= max; i++) {
            System.out.print("S" + i + " : ");
            for (int j = 0; j < result.length; j++) {
                if (result[j] == i) {
                    System.out.print(j + " ");
                }
            }
            System.out.println();
        }
    }
}
